/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.verify;

import picounit.verify.BooleanArrayConstraints;
import picounit.verify.BooleanConstraints;
import picounit.verify.ByteArrayConstraints;
import picounit.verify.ByteConstraints;
import picounit.verify.CharacterArrayConstraints;
import picounit.verify.CharacterConstraints;
import picounit.verify.CollectionConstraints;
import picounit.verify.DoubleArrayConstraints;
import picounit.verify.DoubleConstraints;
import picounit.verify.ExtendedStringConstraints;
import picounit.verify.FileConstraints;
import picounit.verify.FloatArrayConstraints;
import picounit.verify.FloatConstraints;
import picounit.verify.IntegerArrayConstraints;
import picounit.verify.IntegerConstraints;
import picounit.verify.ListConstraints;
import picounit.verify.LongArrayConstraints;
import picounit.verify.LongConstraints;
import picounit.verify.SetConstraints;
import picounit.verify.ShortArrayConstraints;
import picounit.verify.ShortConstraints;
import picounit.verify.StringArrayConstraints;
import picounit.verify.TypedArrayConstraints;
import picounit.verify.TypedConstraints;

import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Set;

public class CombinedConstraints {
	private final Evaluator evaluator;

	private final BooleanConstraints booleanConstraints;
	private final ByteConstraints byteConstraints;
	private final CharacterConstraints charConstraints;
	private final DoubleConstraints doubleConstraints;
	private final FloatConstraints floatConstraints;
	private final IntegerConstraints intConstraints;
	private final LongConstraints longConstraints;
	private final ShortConstraints shortConstraints;
	
	private final FileConstraints fileConstraints;
	private final ExtendedStringConstraints stringConstraints;
	@SuppressWarnings("unchecked")
	private final TypedConstraints typedConstraints;
	
	private final BooleanArrayConstraints booleanArrayConstraints;
	private final ByteArrayConstraints byteArrayConstraints;
	private final CharacterArrayConstraints characterArrayConstraints;
	private final DoubleArrayConstraints doubleArrayConstraints;
	private final FloatArrayConstraints floatArrayConstraints;
	private final IntegerArrayConstraints integerArrayConstraints;
	private final LongArrayConstraints longArrayConstraints;
	private final ShortArrayConstraints shortArrayConstraints;
	private final StringArrayConstraints stringArrayConstraints;
	@SuppressWarnings("unchecked")
	private final TypedArrayConstraints typedArrayConstraints;
	
	@SuppressWarnings("unchecked")
	private final CollectionConstraints collectionConstraints;
	@SuppressWarnings("unchecked")
	private final ListConstraints listConstraints;
	@SuppressWarnings("unchecked")
	private final SetConstraints setConstraints;

	public CombinedConstraints(Evaluator evaluator) {
		this.evaluator = evaluator;
		this.booleanConstraints = new DefaultBooleanConstraints(evaluator);
		this.byteConstraints = new DefaultByteConstraints(evaluator);
		this.charConstraints = new DefaultCharacterConstraints(evaluator);
		this.doubleConstraints = new DefaultDoubleConstraints(evaluator);
		this.floatConstraints = new DefaultFloatConstraints(evaluator);
		this.intConstraints = new DefaultIntegerConstraints(evaluator);
		this.longConstraints = new DefaultLongConstraints(evaluator);
		this.shortConstraints = new DefaultShortConstraints(evaluator);

		this.fileConstraints = new DefaultFileConstraints(evaluator);
		this.typedConstraints = new TypedConstraintsImpl(evaluator);

		this.booleanArrayConstraints = new BooleanArrayConstraintsImpl(evaluator);
		this.byteArrayConstraints = new DefaultByteArrayConstraints(evaluator);
		this.characterArrayConstraints = new CharacterArrayConstraintsImpl(evaluator);
		this.doubleArrayConstraints = new DefaultDoubleArrayConstraints(evaluator);
		this.floatArrayConstraints = new FloatArrayConstraintsImpl(evaluator);
		this.integerArrayConstraints = new IntegerArrayConstraintsImpl(evaluator);
		this.longArrayConstraints = new LongArrayConstraintsImpl(evaluator);
		this.shortArrayConstraints = new ShortArrayConstraintsImpl(evaluator);
		this.stringArrayConstraints = new StringArrayConstraintsImpl(evaluator);
		this.typedArrayConstraints = new TypedArrayConstraintsImpl(evaluator);

		this.collectionConstraints = new DefaultCollectionConstraints(evaluator);
		this.listConstraints = new DefaultListConstraints(evaluator);
		this.setConstraints = new DefaultSetConstraints(evaluator);

		this.stringConstraints = new DefaultStringConstraints(evaluator, booleanConstraints,
			byteConstraints, charConstraints, doubleConstraints, floatConstraints,
			intConstraints, longConstraints, shortConstraints, fileConstraints,
			typedConstraints, booleanArrayConstraints, byteArrayConstraints,
			characterArrayConstraints, doubleArrayConstraints, floatArrayConstraints,
			integerArrayConstraints, longArrayConstraints, shortArrayConstraints,
			stringArrayConstraints, typedArrayConstraints, collectionConstraints,
			listConstraints, setConstraints);
	}

	public BooleanConstraints constraintsFor(boolean value) {
		evaluator.setValue(value);

		return booleanConstraints;
	}

	public ByteConstraints constraintsFor(byte value) {
		evaluator.setValue(value);
		
		return byteConstraints;
	}

	public CharacterConstraints constraintsFor(char value) {
		evaluator.setValue(value);
		
		return charConstraints;
	}

	public DoubleConstraints constraintsFor(double value) {
		evaluator.setValue(value);
		
		return doubleConstraints;
	}

	public FloatConstraints constraintsFor(float value) {
		evaluator.setValue(value);
		
		return floatConstraints;
	}

	public IntegerConstraints constraintsFor(int value) {
		evaluator.setValue(value);
		
		return intConstraints;
	}

	public LongConstraints constraintsFor(long value) {
		evaluator.setValue(value);
		
		return longConstraints;
	}

	public ShortConstraints constraintsFor(short value) {
		evaluator.setValue(value);
		
		return shortConstraints;
	}

	public FileConstraints constraintsFor(File value) {
		evaluator.setValue(value);
		
		return fileConstraints;
	}

	public ExtendedStringConstraints constraintsFor(String value) {
		evaluator.setValue(value);

		return stringConstraints;
	}

	@SuppressWarnings("unchecked")
	public <T> TypedConstraints<T> constraintsFor(T value) {
		evaluator.setValue(value);
		
		return typedConstraints;
	}

	public BooleanArrayConstraints constraintsFor(boolean[] value) {
		evaluator.setValue(value);
		
		return booleanArrayConstraints;
	}

	public ByteArrayConstraints constraintsFor(byte[] value) {
		evaluator.setValue(value);
		
		return byteArrayConstraints;
	}

	public CharacterArrayConstraints constraintsFor(char[] value) {
		evaluator.setValue(value);
		
		return characterArrayConstraints;
	}

	public DoubleArrayConstraints constraintsFor(double[] value) {
		evaluator.setValue(value);
		
		return doubleArrayConstraints;
	}

	public FloatArrayConstraints constraintsFor(float[] value) {
		evaluator.setValue(value);
		
		return floatArrayConstraints;
	}

	public IntegerArrayConstraints constraintsFor(int[] value) {
		evaluator.setValue(value);
		
		return integerArrayConstraints;
	}

	public LongArrayConstraints constraintsFor(long[] value) {
		evaluator.setValue(value);
		
		return longArrayConstraints;
	}

	public ShortArrayConstraints constraintsFor(short[] value) {
		evaluator.setValue(value);
		
		return shortArrayConstraints;
	}

	public StringArrayConstraints constraintsFor(String[] value) {
		evaluator.setValue(value);
		
		return stringArrayConstraints;
	}

	@SuppressWarnings("unchecked")
	public <T> TypedArrayConstraints constraintsFor(T[] value) {
		evaluator.setValue(value);
		
		return typedArrayConstraints;
	}

	@SuppressWarnings("unchecked")
	public <T> CollectionConstraints<T> constraintsFor(Collection<T> value) {
		evaluator.setValue(value);
		
		return collectionConstraints;
	}

	@SuppressWarnings("unchecked")
	public <T> ListConstraints<T> constraintsFor(List<T> value) {
		evaluator.setValue(value);
		
		return listConstraints;
	}

	@SuppressWarnings("unchecked")
	public <T> SetConstraints<T> constraintsFor(Set<T> value) {
		evaluator.setValue(value);

		return setConstraints;
	}
}